import {AcGameObject} from "./AcGameObject";
import {Wall} from "./Wall";
import {Snake} from "@/assets/scripts/Snake";
import {useStore} from "vuex";

export class GameMap extends AcGameObject {
    constructor(ctx, parent) {
        super();
        this.ctx = ctx;
        this.parent = parent;
        this.L = 0;

        this.store = useStore();
        this.rows = this.store.state.pk.gamemap.length;
        this.cols = this.store.state.pk.gamemap[0].length;
        this.walls = [];

        this.snakes = [
            new Snake({
                id: 0, color: "blue", r: this.rows - 2, c: 1
            }, this),
            new Snake({
                id: 1, color: "red", r: 1, c: this.cols - 2
            }, this),
        ]
    }

    /**
     * // 判断两条蛇是否准备下一回合
     */
    check_ready() {
        for (const snake of this.snakes) {
            if (snake.status === "idle" && snake.direction !== -1) {
                return true;
            }
        }
        return false;
    }

    next_step() {

        for (const snake of this.snakes) {
            if (snake.status === "idle" && snake.direction !== -1) {
                // 这里实现蛇的移动逻辑
                snake.next_step();
            }
        }
    }

    add_listening_events() {
        if (this.store.state.record.is_record) {
            let k = 0;
            const a_steps = this.store.state.record.a_steps;
            const b_steps = this.store.state.record.b_steps;
            const loser = this.store.state.record.loser;
            const [snake0, snake1] = this.snakes;
            const interval_id = setInterval(() => {
                if (k >= a_steps.length-1) {
                    snake0.set_direction(parseInt(a_steps[k]));
                    snake1.set_direction(parseInt(b_steps[k]));
                    if (loser === "all" || loser === "A") {
                        snake0.status = "die";
                    }
                    if (loser === "all" || loser === "B") {
                        snake1.status = "die";
                    }
                    clearInterval(interval_id);
                    this.store.commit("updateIsRecord", false);
                } else {
                    snake0.set_direction(parseInt(a_steps[k]));
                    snake1.set_direction(parseInt(b_steps[k]));
                }
                k++;
            }, 300);
        } else {
            this.ctx.canvas.focus();
            this.ctx.canvas.addEventListener("keydown", e => {
                // console.log(e.key);
                let d = -1;
                if (e.key === 'w') d = 0;
                else if (e.key === 'd') d = 1;
                else if (e.key === 's') d = 2;
                else if (e.key === 'a') d = 3;

                if (d >= 0) {
                    // console.log(d);
                    this.store.state.pk.socket.send(JSON.stringify({
                        event: "move",
                        direction: d,
                    }))
                }
            });
        }

    }

    create_walls() {

        const g = this.store.state.pk.gamemap;
        for (let r = 0; r < this.rows; r++) {
            for (let c = 0; c < this.cols; c++) {
                if (g[r][c]) {
                    this.walls.push(new Wall(r, c, this));
                }
            }
        }
    }

    start() {
        this.create_walls();
        this.add_listening_events();
    }

    update_size() {
        this.L = Math.min(
            this.parent.clientWidth / this.cols,
            this.parent.clientHeight / this.rows
        );
        this.ctx.canvas.width = this.L * this.cols;
        this.ctx.canvas.height = this.L * this.rows;
    }

    update() {
        this.update_size();
        if (this.check_ready()) {
            console.log("ready");
            this.next_step();
        }
        this.render();
    }

    render() {
        const color_even = "#a3d049";
        const color_odd = "#abd653";
        for (let r = 0; r < this.rows; r++) {
            for (let c = 0; c < this.cols; c++) {
                if ((c + r) % 2 == 0) {
                    this.ctx.fillStyle = color_even;
                } else {
                    this.ctx.fillStyle = color_odd;
                }
                this.ctx.fillRect(c * this.L, r * this.L, this.L, this.L);
            }
        }
    }
}
